From: Eric Dumazet <dada1@cosmosbay.com>
To: Ingo Molnar <mingo@elte.hu>
Cc: Tejun Heo <htejun@gmail.com>,
Jeremy Fitzhardinge <jeremy@goop.org>,
linux kernel <linux-kernel@vger.kernel.org>,
Linux Netdev List <netdev@vger.kernel.org>,
Rusty Russell <rusty@rustcorp.com.au>
Subject: [PATCH] percpu: convert SNMP mibs to new infra
Date: Thu, 02 Apr 2009 10:07:40 +0200 [thread overview]
Message-ID: <49D4724C.7010200@cosmosbay.com> (raw)
In-Reply-To: <20090402040537.GB30442@elte.hu>
Ingo Molnar a écrit :
> * Tejun Heo <htejun@gmail.com> wrote:
>
>> Hello, Eric, Ingo.
>>
>> Eric Dumazet wrote:
>>> diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h
>>> index aee103b..6b82f6b 100644
>>> --- a/arch/x86/include/asm/percpu.h
>>> +++ b/arch/x86/include/asm/percpu.h
>>> @@ -135,6 +135,9 @@ do { \
>>> #define percpu_read(var) percpu_from_op("mov", per_cpu__##var)
>>> #define percpu_write(var, val) percpu_to_op("mov", per_cpu__##var, val)
>>> #define percpu_add(var, val) percpu_to_op("add", per_cpu__##var, val)
>>> +#define indir_percpu_add(var, val) percpu_to_op("add", *(var), val)
>>> +#define indir_percpu_inc(var) percpu_to_op("add", *(var), 1)
>>> +#define indir_percpu_dec(var) percpu_to_op("add", *(var), -1)
>>> #define percpu_sub(var, val) percpu_to_op("sub", per_cpu__##var, val)
>>> #define percpu_and(var, val) percpu_to_op("and", per_cpu__##var, val)
>>> #define percpu_or(var, val) percpu_to_op("or", per_cpu__##var, val)
>> The final goal is to unify static and dynamic accesses but we
>> aren't there yet, so, for the time being, we'll need some interim
>> solutions. I would prefer percpu_ptr_add() tho.
>
> Yep, that's the standard naming scheme for new APIs: generic to
> specific, left to right.
>
Here is a second version of the patch, with percpu_ptr_xxx convention,
and more polished form (snmp_mib_free() was forgoten in previous RFC)
Thank you all
[PATCH] percpu: convert SNMP mibs to new infra
Some arches can use percpu infrastructure for safe changes to mibs.
(percpu_add() is safe against preemption and interrupts), but
we want the real thing (a single instruction), not an emulation.
On arches still using an emulation, its better to keep the two views
per mib and preemption disable/enable
This shrinks size of mibs by 50%, but also shrinks vmlinux text size
(minimum IPV4 config)
$ size vmlinux.old vmlinux.new
text data bss dec hex filename
4308458 561092 1728512 6598062 64adae vmlinux.old
4303834 561092 1728512 6593438 649b9e vmlinux.new
Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
---
arch/x86/include/asm/percpu.h | 3 +++
include/net/snmp.h | 27 ++++++++++++++++++++++-----
net/ipv4/af_inet.c | 31 ++++++++++++++++++-------------
3 files changed, 43 insertions(+), 18 deletions(-)
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h
index aee103b..f8081e4 100644
--- a/arch/x86/include/asm/percpu.h
+++ b/arch/x86/include/asm/percpu.h
@@ -135,6 +135,9 @@ do { \
#define percpu_read(var) percpu_from_op("mov", per_cpu__##var)
#define percpu_write(var, val) percpu_to_op("mov", per_cpu__##var, val)
#define percpu_add(var, val) percpu_to_op("add", per_cpu__##var, val)
+#define percpu_ptr_add(var, val) percpu_to_op("add", *(var), val)
+#define percpu_ptr_inc(var) percpu_ptr_add(var, 1)
+#define percpu_ptr_dec(var) percpu_ptr_add(var, -1)
#define percpu_sub(var, val) percpu_to_op("sub", per_cpu__##var, val)
#define percpu_and(var, val) percpu_to_op("and", per_cpu__##var, val)
#define percpu_or(var, val) percpu_to_op("or", per_cpu__##var, val)
diff --git a/include/net/snmp.h b/include/net/snmp.h
index 57c9362..1ba584b 100644
--- a/include/net/snmp.h
+++ b/include/net/snmp.h
@@ -123,15 +123,31 @@ struct linux_xfrm_mib {
};
/*
- * FIXME: On x86 and some other CPUs the split into user and softirq parts
+ * On x86 and some other CPUs the split into user and softirq parts
* is not needed because addl $1,memory is atomic against interrupts (but
- * atomic_inc would be overkill because of the lock cycles). Wants new
- * nonlocked_atomic_inc() primitives -AK
+ * atomic_inc would be overkill because of the lock cycles).
*/
+#ifdef CONFIG_X86
+# define SNMP_ARRAY_SZ 1
+#else
+# define SNMP_ARRAY_SZ 2
+#endif
+
#define DEFINE_SNMP_STAT(type, name) \
- __typeof__(type) *name[2]
+ __typeof__(type) *name[SNMP_ARRAY_SZ]
#define DECLARE_SNMP_STAT(type, name) \
- extern __typeof__(type) *name[2]
+ extern __typeof__(type) *name[SNMP_ARRAY_SZ]
+
+#if SNMP_ARRAY_SZ == 1
+#define SNMP_INC_STATS(mib, field) percpu_ptr_inc(&mib[0]->mibs[field])
+#define SNMP_INC_STATS_BH(mib, field) SNMP_INC_STATS(mib, field)
+#define SNMP_INC_STATS_USER(mib, field) SNMP_INC_STATS(mib, field)
+#define SNMP_DEC_STATS(mib, field) percpu_ptr_dec(&mib[0]->mibs[field])
+#define SNMP_ADD_STATS_BH(mib, field, addend) \
+ percpu_ptr_add(&mib[0]->mibs[field], addend)
+#define SNMP_ADD_STATS_USER(mib, field, addend) \
+ percpu_ptr_add(&mib[0]->mibs[field], addend)
+#else
#define SNMP_STAT_BHPTR(name) (name[0])
#define SNMP_STAT_USRPTR(name) (name[1])
@@ -160,5 +176,6 @@ struct linux_xfrm_mib {
per_cpu_ptr(mib[1], get_cpu())->mibs[field] += addend; \
put_cpu(); \
} while (0)
+#endif
#endif
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 7f03373..4df3a76 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1366,36 +1366,41 @@ unsigned long snmp_fold_field(void *mib[], int offt)
for_each_possible_cpu(i) {
res += *(((unsigned long *) per_cpu_ptr(mib[0], i)) + offt);
+#if SNMP_ARRAY_SZ == 2
res += *(((unsigned long *) per_cpu_ptr(mib[1], i)) + offt);
+#endif
}
return res;
}
EXPORT_SYMBOL_GPL(snmp_fold_field);
-int snmp_mib_init(void *ptr[2], size_t mibsize)
+int snmp_mib_init(void *ptr[SNMP_ARRAY_SZ], size_t mibsize)
{
BUG_ON(ptr == NULL);
ptr[0] = __alloc_percpu(mibsize, __alignof__(unsigned long long));
if (!ptr[0])
- goto err0;
+ return -ENOMEM;
+#if SNMP_ARRAY_SZ == 2
ptr[1] = __alloc_percpu(mibsize, __alignof__(unsigned long long));
- if (!ptr[1])
- goto err1;
+ if (!ptr[1]) {
+ free_percpu(ptr[0]);
+ ptr[0] = NULL;
+ return -ENOMEM;
+ }
+#endif
return 0;
-err1:
- free_percpu(ptr[0]);
- ptr[0] = NULL;
-err0:
- return -ENOMEM;
}
EXPORT_SYMBOL_GPL(snmp_mib_init);
-void snmp_mib_free(void *ptr[2])
+void snmp_mib_free(void *ptr[SNMP_ARRAY_SZ])
{
+ int i;
+
BUG_ON(ptr == NULL);
- free_percpu(ptr[0]);
- free_percpu(ptr[1]);
- ptr[0] = ptr[1] = NULL;
+ for (i = 0 ; i < SNMP_ARRAY_SZ; i++) {
+ free_percpu(ptr[i]);
+ ptr[i] = NULL;
+ }
}
EXPORT_SYMBOL_GPL(snmp_mib_free);
next prev parent reply other threads:[~2009-04-02 8:08 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-04-01 8:13 [PATCH] x86: percpu_to_op() misses memory and flags clobbers Eric Dumazet
2009-04-01 9:02 ` Jeremy Fitzhardinge
2009-04-01 10:14 ` Eric Dumazet
2009-04-01 16:12 ` Ingo Molnar
2009-04-01 16:41 ` Jeremy Fitzhardinge
2009-04-01 16:44 ` Ingo Molnar
2009-04-01 17:13 ` Eric Dumazet
2009-04-01 18:07 ` Jeremy Fitzhardinge
2009-04-01 18:47 ` Eric Dumazet
2009-04-02 9:52 ` Herbert Xu
2009-04-02 14:12 ` Jeremy Fitzhardinge
2009-04-01 18:44 ` [RFC] percpu: convert SNMP mibs to new infra Eric Dumazet
2009-04-02 0:13 ` Tejun Heo
2009-04-02 4:05 ` Ingo Molnar
2009-04-02 8:07 ` Eric Dumazet [this message]
2009-04-03 0:39 ` [PATCH] " Tejun Heo
2009-04-03 17:10 ` Ingo Molnar
2009-04-02 5:04 ` [RFC] " Rusty Russell
2009-04-02 5:19 ` Eric Dumazet
2009-04-02 11:46 ` Rusty Russell
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=49D4724C.7010200@cosmosbay.com \
--to=dada1@cosmosbay.com \
--cc=htejun@gmail.com \
--cc=jeremy@goop.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=netdev@vger.kernel.org \
--cc=rusty@rustcorp.com.au \
/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).