From: Dave Chinner <david@fromorbit.com> To: xfs@oss.sgi.com Cc: linux-kernel@vger.kernel.org Subject: [PATCH 1/2] percpu_counter: batch size aware __percpu_counter_compare() Date: Wed, 6 May 2015 08:01:38 +1000 [thread overview] Message-ID: <1430863299-9341-2-git-send-email-david@fromorbit.com> (raw) In-Reply-To: <1430863299-9341-1-git-send-email-david@fromorbit.com> From: Dave Chinner <dchinner@redhat.com> From: Dave Chinner <dchinner@redhat.com> XFS uses non-stanard batch sizes for avoiding frequent global counter updates on it's allocated inode counters, as they increment or decrement in batches of 64 inodes. Hence the standard percpu counter batch of 32 means that the counter is effectively a global counter. Currently Xfs uses a batch size of 128 so that it doesn't take the global lock on every single modification. However, Xfs also needs to compare accurately against zero, which means we need to use percpu_counter_compare(), and that has a hard-coded batch size of 32, and hence will spuriously fail to detect when it is supposed to use precise comparisons and hence the accounting goes wrong. Add __percpu_counter_compare() to take a custom batch size so we can use it sanely in XFS and factor percpu_counter_compare() to use it. Signed-off-by: Dave Chinner <dchinner@redhat.com> --- include/linux/percpu_counter.h | 13 ++++++++++++- lib/percpu_counter.c | 6 +++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/include/linux/percpu_counter.h b/include/linux/percpu_counter.h index 50e5009..4c82e60 100644 --- a/include/linux/percpu_counter.h +++ b/include/linux/percpu_counter.h @@ -41,7 +41,12 @@ void percpu_counter_destroy(struct percpu_counter *fbc); void percpu_counter_set(struct percpu_counter *fbc, s64 amount); void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch); s64 __percpu_counter_sum(struct percpu_counter *fbc); -int percpu_counter_compare(struct percpu_counter *fbc, s64 rhs); +int __percpu_counter_compare(struct percpu_counter *fbc, s64 rhs, s32 batch); + +static inline int percpu_counter_compare(struct percpu_counter *fbc, s64 rhs) +{ + return __percpu_counter_compare(fbc, rhs, percpu_counter_batch); +} static inline void percpu_counter_add(struct percpu_counter *fbc, s64 amount) { @@ -116,6 +121,12 @@ static inline int percpu_counter_compare(struct percpu_counter *fbc, s64 rhs) return 0; } +static inline int +percpu_counter_compare(struct percpu_counter *fbc, s64 rhs, s32 batch) +{ + return percpu_counter_compare(fbc, rhs); +} + static inline void percpu_counter_add(struct percpu_counter *fbc, s64 amount) { diff --git a/lib/percpu_counter.c b/lib/percpu_counter.c index 48144cd..f051d69 100644 --- a/lib/percpu_counter.c +++ b/lib/percpu_counter.c @@ -197,13 +197,13 @@ static int percpu_counter_hotcpu_callback(struct notifier_block *nb, * Compare counter against given value. * Return 1 if greater, 0 if equal and -1 if less */ -int percpu_counter_compare(struct percpu_counter *fbc, s64 rhs) +int __percpu_counter_compare(struct percpu_counter *fbc, s64 rhs, s32 batch) { s64 count; count = percpu_counter_read(fbc); /* Check to see if rough count will be sufficient for comparison */ - if (abs(count - rhs) > (percpu_counter_batch*num_online_cpus())) { + if (abs(count - rhs) > (batch * num_online_cpus())) { if (count > rhs) return 1; else @@ -218,7 +218,7 @@ int percpu_counter_compare(struct percpu_counter *fbc, s64 rhs) else return 0; } -EXPORT_SYMBOL(percpu_counter_compare); +EXPORT_SYMBOL(__percpu_counter_compare); static int __init percpu_counter_startup(void) { -- 2.0.0
WARNING: multiple messages have this Message-ID (diff)
From: Dave Chinner <david@fromorbit.com> To: xfs@oss.sgi.com Cc: linux-kernel@vger.kernel.org Subject: [PATCH 1/2] percpu_counter: batch size aware __percpu_counter_compare() Date: Wed, 6 May 2015 08:01:38 +1000 [thread overview] Message-ID: <1430863299-9341-2-git-send-email-david@fromorbit.com> (raw) In-Reply-To: <1430863299-9341-1-git-send-email-david@fromorbit.com> From: Dave Chinner <dchinner@redhat.com> From: Dave Chinner <dchinner@redhat.com> XFS uses non-stanard batch sizes for avoiding frequent global counter updates on it's allocated inode counters, as they increment or decrement in batches of 64 inodes. Hence the standard percpu counter batch of 32 means that the counter is effectively a global counter. Currently Xfs uses a batch size of 128 so that it doesn't take the global lock on every single modification. However, Xfs also needs to compare accurately against zero, which means we need to use percpu_counter_compare(), and that has a hard-coded batch size of 32, and hence will spuriously fail to detect when it is supposed to use precise comparisons and hence the accounting goes wrong. Add __percpu_counter_compare() to take a custom batch size so we can use it sanely in XFS and factor percpu_counter_compare() to use it. Signed-off-by: Dave Chinner <dchinner@redhat.com> --- include/linux/percpu_counter.h | 13 ++++++++++++- lib/percpu_counter.c | 6 +++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/include/linux/percpu_counter.h b/include/linux/percpu_counter.h index 50e5009..4c82e60 100644 --- a/include/linux/percpu_counter.h +++ b/include/linux/percpu_counter.h @@ -41,7 +41,12 @@ void percpu_counter_destroy(struct percpu_counter *fbc); void percpu_counter_set(struct percpu_counter *fbc, s64 amount); void __percpu_counter_add(struct percpu_counter *fbc, s64 amount, s32 batch); s64 __percpu_counter_sum(struct percpu_counter *fbc); -int percpu_counter_compare(struct percpu_counter *fbc, s64 rhs); +int __percpu_counter_compare(struct percpu_counter *fbc, s64 rhs, s32 batch); + +static inline int percpu_counter_compare(struct percpu_counter *fbc, s64 rhs) +{ + return __percpu_counter_compare(fbc, rhs, percpu_counter_batch); +} static inline void percpu_counter_add(struct percpu_counter *fbc, s64 amount) { @@ -116,6 +121,12 @@ static inline int percpu_counter_compare(struct percpu_counter *fbc, s64 rhs) return 0; } +static inline int +percpu_counter_compare(struct percpu_counter *fbc, s64 rhs, s32 batch) +{ + return percpu_counter_compare(fbc, rhs); +} + static inline void percpu_counter_add(struct percpu_counter *fbc, s64 amount) { diff --git a/lib/percpu_counter.c b/lib/percpu_counter.c index 48144cd..f051d69 100644 --- a/lib/percpu_counter.c +++ b/lib/percpu_counter.c @@ -197,13 +197,13 @@ static int percpu_counter_hotcpu_callback(struct notifier_block *nb, * Compare counter against given value. * Return 1 if greater, 0 if equal and -1 if less */ -int percpu_counter_compare(struct percpu_counter *fbc, s64 rhs) +int __percpu_counter_compare(struct percpu_counter *fbc, s64 rhs, s32 batch) { s64 count; count = percpu_counter_read(fbc); /* Check to see if rough count will be sufficient for comparison */ - if (abs(count - rhs) > (percpu_counter_batch*num_online_cpus())) { + if (abs(count - rhs) > (batch * num_online_cpus())) { if (count > rhs) return 1; else @@ -218,7 +218,7 @@ int percpu_counter_compare(struct percpu_counter *fbc, s64 rhs) else return 0; } -EXPORT_SYMBOL(percpu_counter_compare); +EXPORT_SYMBOL(__percpu_counter_compare); static int __init percpu_counter_startup(void) { -- 2.0.0 _______________________________________________ xfs mailing list xfs@oss.sgi.com http://oss.sgi.com/mailman/listinfo/xfs
next prev parent reply other threads:[~2015-05-05 22:02 UTC|newest] Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top 2015-05-05 22:01 [PATCH 0/2] xfs: fix inode count underrun Dave Chinner 2015-05-05 22:01 ` Dave Chinner 2015-05-05 22:01 ` Dave Chinner [this message] 2015-05-05 22:01 ` [PATCH 1/2] percpu_counter: batch size aware __percpu_counter_compare() Dave Chinner 2015-05-06 4:36 ` Christoph Hellwig 2015-05-06 4:36 ` Christoph Hellwig 2015-05-06 4:46 ` Christoph Hellwig 2015-05-06 4:46 ` Christoph Hellwig 2015-05-06 5:43 ` Dave Chinner 2015-05-06 5:43 ` Dave Chinner 2015-05-06 5:53 ` Dave Chinner 2015-05-06 5:53 ` Dave Chinner 2015-05-06 6:11 ` Dave Chinner 2015-05-06 6:11 ` Dave Chinner 2015-05-05 22:01 ` [PATCH 2/2] xfs: inode counter needs to use __percpu_counter_compare Dave Chinner 2015-05-05 22:01 ` Dave Chinner 2015-05-06 4:38 ` Christoph Hellwig 2015-05-06 4:38 ` Christoph Hellwig 2015-05-06 5:45 ` Dave Chinner 2015-05-06 5:45 ` Dave Chinner 2015-05-12 23:52 [PATCH 0/2 v2] percpu_counter: xfs requires custom compare batch size Dave Chinner 2015-05-12 23:52 ` [PATCH 1/2] percpu_counter: batch size aware __percpu_counter_compare() Dave Chinner 2015-05-12 23:52 ` Dave Chinner 2015-05-13 13:59 ` Tejun Heo 2015-05-13 13:59 ` Tejun Heo 2015-05-14 0:55 ` Dave Chinner 2015-05-14 0:55 ` Dave Chinner 2015-05-14 15:02 ` Tejun Heo 2015-05-14 15:02 ` Tejun Heo
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=1430863299-9341-2-git-send-email-david@fromorbit.com \ --to=david@fromorbit.com \ --cc=linux-kernel@vger.kernel.org \ --cc=xfs@oss.sgi.com \ /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: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.