linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Dmitry Monakhov <dmonakhov@openvz.org>
To: Jan Kara <jack@suse.cz>
Cc: linux-fsdevel@vger.kernel.org
Subject: Re: [PATCH] quota: Convert quota statistics to generic percpu_counter
Date: Thu, 27 May 2010 19:45:56 +0400	[thread overview]
Message-ID: <87vda99wlm.fsf@openvz.org> (raw)
In-Reply-To: <1274966859-18289-1-git-send-email-jack@suse.cz> (Jan Kara's message of "Thu, 27 May 2010 15:27:39 +0200")

Jan Kara <jack@suse.cz> writes:

> From: Dmitry Monakhov <dmonakhov@openvz.org>
>
> Generic per-cpu counter has some memory overhead but it is negligible for
> modern systems and embedded systems compile without quota support.  And code
> reuse is a good thing. This patch should fix complain from preemptive kernels
> which was introduced by dde9588853b1bde.
>
> [Jan Kara: Fixed patch to work on 32-bit archs as well]
Ohh. Thanks for fixing that.
>
> Reported-by: Rafael J. Wysocki <rjw@sisk.pl>
> Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
> Signed-off-by: Jan Kara <jack@suse.cz>
> ---
>  Dmitry, I have fixed the patch to use 'int' as quota stats used to instead
> of s64 you used. Now I plan to push it to Linus to fix the reported bug...
>
>  fs/quota/dquot.c      |   45 ++++++++++++---------------------------------
>  include/linux/quota.h |   16 ++++------------
>  2 files changed, 16 insertions(+), 45 deletions(-)
>
> diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
> index 1ff9131..36e2af8 100644
> --- a/fs/quota/dquot.c
> +++ b/fs/quota/dquot.c
> @@ -228,10 +228,6 @@ static struct hlist_head *dquot_hash;
>  
>  struct dqstats dqstats;
>  EXPORT_SYMBOL(dqstats);
> -#ifdef CONFIG_SMP
> -struct dqstats *dqstats_pcpu;
> -EXPORT_SYMBOL(dqstats_pcpu);
> -#endif
>  
>  static qsize_t inode_get_rsv_space(struct inode *inode);
>  static void __dquot_initialize(struct inode *inode, int type);
> @@ -676,27 +672,10 @@ static void prune_dqcache(int count)
>  	}
>  }
>  
> -static int dqstats_read(unsigned int type)
> -{
> -	int count = 0;
> -#ifdef CONFIG_SMP
> -	int cpu;
> -	for_each_possible_cpu(cpu)
> -		count += per_cpu_ptr(dqstats_pcpu, cpu)->stat[type];
> -	/* Statistics reading is racy, but absolute accuracy isn't required */
> -	if (count < 0)
> -		count = 0;
> -#else
> -	count = dqstats.stat[type];
> -#endif
> -	return count;
> -}
> -
>  /*
>   * This is called from kswapd when we think we need some
>   * more memory
>   */
> -
>  static int shrink_dqcache_memory(int nr, gfp_t gfp_mask)
>  {
>  	if (nr) {
> @@ -704,7 +683,8 @@ static int shrink_dqcache_memory(int nr, gfp_t gfp_mask)
>  		prune_dqcache(nr);
>  		spin_unlock(&dq_list_lock);
>  	}
> -	return (dqstats_read(DQST_FREE_DQUOTS)/100) * sysctl_vfs_cache_pressure;
> +	return (percpu_counter_read_positive(&dqstats.counter[DQST_FREE_DQUOTS])
> +		/100) * sysctl_vfs_cache_pressure;
>  }
>  
>  static struct shrinker dqcache_shrinker = {
> @@ -2497,11 +2477,11 @@ EXPORT_SYMBOL(dquot_quotactl_ops);
>  static int do_proc_dqstats(struct ctl_table *table, int write,
>  		     void __user *buffer, size_t *lenp, loff_t *ppos)
>  {
> -#ifdef CONFIG_SMP
> -	/* Update global table */
>  	unsigned int type = (int *)table->data - dqstats.stat;
> -	dqstats.stat[type] = dqstats_read(type);
> -#endif
> +
> +	/* Update global table */
> +	dqstats.stat[type] =
> +			percpu_counter_sum_positive(&dqstats.counter[type]);
>  	return proc_dointvec(table, write, buffer, lenp, ppos);
>  }
>  
> @@ -2594,7 +2574,7 @@ static ctl_table sys_table[] = {
>  
>  static int __init dquot_init(void)
>  {
> -	int i;
> +	int i, ret;
>  	unsigned long nr_hash, order;
>  
>  	printk(KERN_NOTICE "VFS: Disk quotas %s\n", __DQUOT_VERSION__);
> @@ -2612,12 +2592,11 @@ static int __init dquot_init(void)
>  	if (!dquot_hash)
>  		panic("Cannot create dquot hash table");
>  
> -#ifdef CONFIG_SMP
> -	dqstats_pcpu = alloc_percpu(struct dqstats);
> -	if (!dqstats_pcpu)
> -		panic("Cannot create dquot stats table");
> -#endif
> -	memset(&dqstats, 0, sizeof(struct dqstats));
> +	for (i = 0; i < _DQST_DQSTAT_LAST; i++) {
> +		ret = percpu_counter_init(&dqstats.counter[i], 0);
> +		if (ret)
> +			panic("Cannot create dquot stat counters");
> +	}
>  
>  	/* Find power-of-two hlist_heads which can fit into allocation */
>  	nr_hash = (1UL << order) * PAGE_SIZE / sizeof(struct hlist_head);
> diff --git a/include/linux/quota.h b/include/linux/quota.h
> index 2789d07..94c1f03 100644
> --- a/include/linux/quota.h
> +++ b/include/linux/quota.h
> @@ -174,8 +174,7 @@ enum {
>  #include <linux/rwsem.h>
>  #include <linux/spinlock.h>
>  #include <linux/wait.h>
> -#include <linux/percpu.h>
> -#include <linux/smp.h>
> +#include <linux/percpu_counter.h>
>  
>  #include <linux/dqblk_xfs.h>
>  #include <linux/dqblk_v1.h>
> @@ -254,6 +253,7 @@ enum {
>  
>  struct dqstats {
>  	int stat[_DQST_DQSTAT_LAST];
> +	struct percpu_counter counter[_DQST_DQSTAT_LAST];
>  };
>  
>  extern struct dqstats *dqstats_pcpu;
> @@ -261,20 +261,12 @@ extern struct dqstats dqstats;
>  
>  static inline void dqstats_inc(unsigned int type)
>  {
> -#ifdef CONFIG_SMP
> -	per_cpu_ptr(dqstats_pcpu, smp_processor_id())->stat[type]++;
> -#else
> -	dqstats.stat[type]++;
> -#endif
> +	percpu_counter_inc(&dqstats.counter[type]);
>  }
>  
>  static inline void dqstats_dec(unsigned int type)
>  {
> -#ifdef CONFIG_SMP
> -	per_cpu_ptr(dqstats_pcpu, smp_processor_id())->stat[type]--;
> -#else
> -	dqstats.stat[type]--;
> -#endif
> +	percpu_counter_dec(&dqstats.counter[type]);
>  }
>  
>  #define DQ_MOD_B	0	/* dquot modified since read */

  reply	other threads:[~2010-05-27 15:46 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-05-27 13:27 [PATCH] quota: Convert quota statistics to generic percpu_counter Jan Kara
2010-05-27 15:45 ` Dmitry Monakhov [this message]
  -- strict thread matches above, loose matches on Subject: below --
2010-05-25 11:29 Dmitry Monakhov
2010-05-25 11:39 ` Dmitry Monakhov
2010-05-25 13:47 ` Jan Kara

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87vda99wlm.fsf@openvz.org \
    --to=dmonakhov@openvz.org \
    --cc=jack@suse.cz \
    --cc=linux-fsdevel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).