Change Networking mibs to use kmalloc_percpu -- 1/3

Change Networking mibs to use kmalloc_percpu -- 1/3

Post by Ravikiran G Thirumala » Thu, 05 Dec 2002 14:50:10



Here's a patchset to enable networking mibs to use kmalloc_percpu instead
of the traditional padded NR_CPUS arrays.

Advantages:
1. Removes NR_CPUS bloat due to static definition
2. Can support node local allocation
3. Will work with modules

The changes have been split for ipv4, ipv6 and sctp.  We can later do away
with the __pad and associated logic duing proc reporting (in the mibs)
if this patchset is acceptable.

This patch is 1 of 3

D: Name: ipv4mibs-2.5.50-1.patch
D: Author: Ravikiran Thirumalai
D: Description: Changes ipv4 stats to use kmalloc_percpu from the traditional
D:              padded NR_CPUS arrays

 include/net/icmp.h       |   15 ++++++-
 include/net/ip.h         |    6 +-
 include/net/snmp.h       |   39 +++++++++++++------
 include/net/tcp.h        |    6 +-
 include/net/udp.h        |    2
 net/ipv4/af_inet.c       |   61 +++++++++++++++++++++++++++++
 net/ipv4/icmp.c          |   96 ++++++++++++++++++++++-------------------------
 net/ipv4/ip_input.c      |    2
 net/ipv4/proc.c          |   37 +++++++++---------
 net/ipv4/tcp.c           |   13 +++---
 net/ipv4/tcp_input.c     |    4 -
 net/ipv4/tcp_minisocks.c |    4 -
 net/ipv4/tcp_timer.c     |    3 -
 net/ipv4/udp.c           |    2
 14 files changed, 190 insertions(+), 100 deletions(-)

diff -ruN -X dontdiff linux-2.5.50/include/net/icmp.h mibstats-2.5.50/include/net/icmp.h
--- linux-2.5.50/include/net/icmp.h     Thu Nov 28 04:06:18 2002
+++ mibstats-2.5.50/include/net/icmp.h  Wed Dec  4 12:13:33 2002
@@ -23,6 +23,7 @@

 #include <net/sock.h>
 #include <net/protocol.h>
+#include <net/snmp.h>
 #include <linux/ip.h>

 struct icmp_err {
@@ -31,10 +32,22 @@
 };

 extern struct icmp_err icmp_err_convert[];
-extern struct icmp_mib icmp_statistics[NR_CPUS*2];
+DECLARE_SNMP_STAT(struct icmp_mib, icmp_statistics);
 #define ICMP_INC_STATS(field)          SNMP_INC_STATS(icmp_statistics, field)
 #define ICMP_INC_STATS_BH(field)       SNMP_INC_STATS_BH(icmp_statistics, field)
 #define ICMP_INC_STATS_USER(field)     SNMP_INC_STATS_USER(icmp_statistics, field)
+#define ICMP_INC_STATS_FIELD(offt)                                     \
+       (*((unsigned long *) ((void *)                                  \
+                            per_cpu_ptr(icmp_statistics[!in_softirq()],\
+                                        smp_processor_id())) + offt))++;
+#define ICMP_INC_STATS_BH_FIELD(offt)                                  \
+       (*((unsigned long *) ((void *)                                  \
+                            per_cpu_ptr(icmp_statistics[0],            \
+                                        smp_processor_id())) + offt))++;
+#define ICMP_INC_STATS_USER_FIELD(offt)                                        \
+       (*((unsigned long *) ((void *)                                  \
+                            per_cpu_ptr(icmp_statistics[1],            \
+                                        smp_processor_id())) + offt))++;

 extern void    icmp_send(struct sk_buff *skb_in,  int type, int code, u32 info);
 extern int     icmp_rcv(struct sk_buff *skb);
diff -ruN -X dontdiff linux-2.5.50/include/net/ip.h mibstats-2.5.50/include/net/ip.h
--- linux-2.5.50/include/net/ip.h       Thu Nov 28 04:06:15 2002
+++ mibstats-2.5.50/include/net/ip.h    Wed Dec  4 12:13:33 2002
@@ -149,14 +149,16 @@
 };

 extern struct ipv4_config ipv4_config;
-extern struct ip_mib   ip_statistics[NR_CPUS*2];
+DECLARE_SNMP_STAT(struct ip_mib, ip_statistics);
 #define IP_INC_STATS(field)            SNMP_INC_STATS(ip_statistics, field)
 #define IP_INC_STATS_BH(field)         SNMP_INC_STATS_BH(ip_statistics, field)
 #define IP_INC_STATS_USER(field)       SNMP_INC_STATS_USER(ip_statistics, field)
-extern struct linux_mib        net_statistics[NR_CPUS*2];
+DECLARE_SNMP_STAT(struct linux_mib, net_statistics);
 #define NET_INC_STATS(field)           SNMP_INC_STATS(net_statistics, field)
 #define NET_INC_STATS_BH(field)                SNMP_INC_STATS_BH(net_statistics, field)
 #define NET_INC_STATS_USER(field)      SNMP_INC_STATS_USER(net_statistics, field)
+#define NET_ADD_STATS_BH(field, adnd)  SNMP_ADD_STATS_BH(net_statistics, field, adnd)
+#define NET_ADD_STATS_USER(field, adnd)        SNMP_ADD_STATS_USER(net_statistics, field, adnd)

 extern int sysctl_local_port_range[2];
 extern int sysctl_ip_default_ttl;
diff -ruN -X dontdiff linux-2.5.50/include/net/snmp.h mibstats-2.5.50/include/net/snmp.h
--- linux-2.5.50/include/net/snmp.h     Thu Nov 28 04:05:57 2002
+++ mibstats-2.5.50/include/net/snmp.h  Wed Dec  4 12:13:33 2002
@@ -62,7 +62,7 @@
        unsigned long   IpFragFails;
        unsigned long   IpFragCreates;
        unsigned long   __pad[0];
-} ____cacheline_aligned;
+};

 struct ipv6_mib
 {
@@ -89,7 +89,7 @@
        unsigned long   Ip6InMcastPkts;
        unsigned long   Ip6OutMcastPkts;
        unsigned long   __pad[0];
-} ____cacheline_aligned;
+};

 struct icmp_mib
 {
@@ -121,7 +121,7 @@
        unsigned long   IcmpOutAddrMaskReps;
        unsigned long   dummy;
        unsigned long   __pad[0];
-} ____cacheline_aligned;
+};

 struct icmpv6_mib
 {
@@ -159,7 +159,7 @@
        unsigned long   Icmp6OutGroupMembResponses;
        unsigned long   Icmp6OutGroupMembReductions;
        unsigned long   __pad[0];
-} ____cacheline_aligned;
+};

 struct tcp_mib
 {
@@ -178,7 +178,7 @@
        unsigned long   TcpInErrs;
        unsigned long   TcpOutRsts;
        unsigned long   __pad[0];
-} ____cacheline_aligned;
+};

 struct udp_mib
 {
@@ -187,7 +187,7 @@
        unsigned long   UdpInErrors;
        unsigned long   UdpOutDatagrams;
        unsigned long   __pad[0];
-} ____cacheline_aligned;
+};

 /* draft-ietf-sigtran-sctp-mib-07.txt */
 struct sctp_mib
@@ -216,7 +216,7 @@
        unsigned long   SctpValCookieLife;
        unsigned long   SctpMaxInitRetr;
        unsigned long   __pad[0];
-} ____cacheline_aligned;
+};

 struct linux_mib
 {
@@ -286,7 +286,7 @@
        unsigned long   TCPAbortFailed;
        unsigned long   TCPMemoryPressures;
        unsigned long   __pad[0];
-} ____cacheline_aligned;
+};

 /*
@@ -294,8 +294,25 @@
  * 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
  */
-#define SNMP_INC_STATS(mib, field) ((mib)[2*smp_processor_id()+!in_softirq()].field++)
-#define SNMP_INC_STATS_BH(mib, field) ((mib)[2*smp_processor_id()].field++)
-#define SNMP_INC_STATS_USER(mib, field) ((mib)[2*smp_processor_id()+1].field++)
+#define DEFINE_SNMP_STAT(type, name)   \
+       __typeof__(type) *name[2]
+#define DECLARE_SNMP_STAT(type, name)  \
+       extern __typeof__(type) *name[2]
+
+#define SNMP_STAT_USRPTR(name) (name[0])
+#define SNMP_STAT_BHPTR(name)  (name[1])
+
+#define SNMP_INC_STATS_BH(mib, field)  \
+       (per_cpu_ptr(mib[0], smp_processor_id())->field++)
+#define SNMP_INC_STATS_USER(mib, field) \
+       (per_cpu_ptr(mib[1], smp_processor_id())->field++)
+#define SNMP_INC_STATS(mib, field)     \
+       (per_cpu_ptr(mib[!in_softirq()], smp_processor_id())->field++)
+#define SNMP_DEC_STATS(mib, field)     \
+       (per_cpu_ptr(mib[!in_softirq()], smp_processor_id())->field--)
+#define SNMP_ADD_STATS_BH(mib, field, addend)  \
+       (per_cpu_ptr(mib[0], smp_processor_id())->field += addend)
+#define SNMP_ADD_STATS_USER(mib, field, addend)        \
+       (per_cpu_ptr(mib[1], smp_processor_id())->field += addend)

 #endif
diff -ruN -X dontdiff linux-2.5.50/include/net/tcp.h mibstats-2.5.50/include/net/tcp.h
--- linux-2.5.50/include/net/tcp.h      Thu Nov 28 04:05:50 2002
+++ mibstats-2.5.50/include/net/tcp.h   Wed Dec  4 12:13:33 2002
@@ -28,6 +28,7 @@
 #include <linux/tcp.h>
 #include <linux/slab.h>
 #include <linux/cache.h>
+#include <linux/percpu.h>
 #include <net/checksum.h>
 #include <net/sock.h>
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
@@ -630,10 +631,11 @@

 extern struct proto tcp_prot;

-extern struct tcp_mib tcp_statistics[NR_CPUS*2];
+DECLARE_SNMP_STAT(struct tcp_mib, tcp_statistics);
 #define TCP_INC_STATS(field)           SNMP_INC_STATS(tcp_statistics, field)
 #define TCP_INC_STATS_BH(field)                SNMP_INC_STATS_BH(tcp_statistics, field)
 #define TCP_INC_STATS_USER(field)      SNMP_INC_STATS_USER(tcp_statistics, field)
+#define TCP_DEC_STATS(field)           SNMP_DEC_STATS(tcp_statistics, field)

 extern void                    tcp_put_port(struct sock *sk);
 extern void                    __tcp_put_port(struct sock *sk);
@@ -1399,7 +1401,7 @@
                /* fall through */
        default:
                if (oldstate==TCP_ESTABLISHED)
-                       tcp_statistics[smp_processor_id()*2+!in_softirq()].TcpCurrEstab--;
+                       TCP_DEC_STATS(TcpCurrEstab);
        }

        /* Change state AFTER socket is unhashed to avoid closed
diff -ruN -X dontdiff linux-2.5.50/include/net/udp.h mibstats-2.5.50/include/net/udp.h
--- linux-2.5.50/include/net/udp.h      Thu Nov 28 04:06:17 2002
+++ mibstats-2.5.50/include/net/udp.h   Wed Dec  4 12:13:33 2002
@@ -71,7 +71,7 @@
 extern int     udp_ioctl(struct sock *sk, int cmd, unsigned long arg);
 extern int     udp_disconnect(struct sock *sk, int flags);

-extern struct udp_mib udp_statistics[NR_CPUS*2];
+DECLARE_SNMP_STAT(struct udp_mib, udp_statistics);
 #define UDP_INC_STATS(field)           SNMP_INC_STATS(udp_statistics, field)
 #define UDP_INC_STATS_BH(field)                SNMP_INC_STATS_BH(udp_statistics, field)
 #define UDP_INC_STATS_USER(field)      SNMP_INC_STATS_USER(udp_statistics, field)
diff -ruN -X dontdiff linux-2.5.50/net/ipv4/af_inet.c mibstats-2.5.50/net/ipv4/af_inet.c
--- linux-2.5.50/net/ipv4/af_inet.c     Thu Nov 28 04:05:50 2002
+++ mibstats-2.5.50/net/ipv4/af_inet.c  Wed Dec  4 12:13:33 2002
@@ -115,7 +115,7 @@
 #include <linux/mroute.h>
 #endif

-struct linux_mib net_statistics[NR_CPUS * 2];
+DEFINE_SNMP_STAT(struct linux_mib, net_statistics);

 #ifdef INET_REFCNT_DEBUG
 atomic_t inet_sock_nr;
@@ -1055,6 +1055,59 @@
        .handler =      icmp_rcv,
 };

+static int __init init_ipv4_mibs(void)
+{
+       int i;
+
+       net_statistics[0] =
+           kmalloc_percpu(sizeof (struct linux_mib), GFP_KERNEL);
+       net_statistics[1] =
+           kmalloc_percpu(sizeof (struct linux_mib), GFP_KERNEL);
+       ip_statistics[0] = kmalloc_percpu(sizeof (struct ip_mib), GFP_KERNEL);
+       ip_statistics[1] = kmalloc_percpu(sizeof (struct ip_mib), GFP_KERNEL);
+       icmp_statistics[0] =
+           kmalloc_percpu(sizeof (struct icmp_mib), GFP_KERNEL);
+       icmp_statistics[1] =
+           kmalloc_percpu(sizeof (struct icmp_mib), GFP_KERNEL);
+       tcp_statistics[0] = kmalloc_percpu(sizeof (struct tcp_mib), GFP_KERNEL);
+       tcp_statistics[1] = kmalloc_percpu(sizeof (struct tcp_mib), GFP_KERNEL);
+       udp_statistics[0] = kmalloc_percpu(sizeof (struct udp_mib), GFP_KERNEL);
+       udp_statistics[1] = kmalloc_percpu(sizeof (struct udp_mib), GFP_KERNEL);
+       if (!
+           (net_statistics[0]
...

read more »

 
 
 

Change Networking mibs to use kmalloc_percpu -- 1/3

Post by David S. Mille » Thu, 05 Dec 2002 19:10:22



   Date: Wed, 4 Dec 2002 18:05:10 +0530

   Here's a patchset to enable networking mibs to use kmalloc_percpu instead
   of the traditional padded NR_CPUS arrays.

   Advantages:
   1. Removes NR_CPUS bloat due to static definition
   2. Can support node local allocation
   3. Will work with modules

I totally support this work.  Once the kmalloc percpu bits hit
Linus's tree, just retransmit these diffs to me privately and
I'll put them into my net-2.5 tree.

Thanks.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

 
 
 

Change Networking mibs to use kmalloc_percpu -- 1/3

Post by Arnaldo Carvalho de Mel » Fri, 06 Dec 2002 00:40:15


Em Wed, Dec 04, 2002 at 09:01:52AM -0800, David S. Miller escreveu:


>    Date: Wed, 4 Dec 2002 18:05:10 +0530

>    Here's a patchset to enable networking mibs to use kmalloc_percpu instead
>    of the traditional padded NR_CPUS arrays.

>    Advantages:
>    1. Removes NR_CPUS bloat due to static definition
>    2. Can support node local allocation
>    3. Will work with modules

> I totally support this work.  Once the kmalloc percpu bits hit
> Linus's tree, just retransmit these diffs to me privately and
> I'll put them into my net-2.5 tree.

Cool stuff! I was planning to macroise this so that things like this would be
possible without source impact but now its just there, keep it up :-)

- Arnaldo
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in

More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/