aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/proc.c
diff options
context:
space:
mode:
authorEric Dumazet <dada1@cosmosbay.com>2007-11-06 02:38:39 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2007-11-07 07:08:57 -0500
commit286ab3d46058840d68e5d7d52e316c1f7e98c59f (patch)
tree1d70e7895c49d2b148e026aa047efe186697fff9 /net/ipv4/proc.c
parent91781004b9c029ee55b7aa9ef950a373ba865dc6 (diff)
[NET]: Define infrastructure to keep 'inuse' changes in an efficent SMP/NUMA way.
"struct proto" currently uses an array stats[NR_CPUS] to track change on 'inuse' sockets per protocol. If NR_CPUS is big, this means we use a big memory area for this. Moreover, all this memory area is located on a single node on NUMA machines, increasing memory pressure on the boot node. In this patch, I tried to : - Keep a fast !CONFIG_SMP implementation - Keep a fast CONFIG_SMP implementation for often used protocols (tcp,udp,raw,...) - Introduce a NUMA efficient implementation Some helper macros are defined in include/net/sock.h These macros take into account CONFIG_SMP If a "struct proto" is declared without using DEFINE_PROTO_INUSE / REF_PROTO_INUSE macros, it will automatically use a default implementation, using a dynamically allocated percpu zone. This default implementation will be NUMA efficient, but might use 32/64 bytes per possible cpu because of current alloc_percpu() implementation. However it still should be better than previous implementation based on stats[NR_CPUS] field. When a "struct proto" is changed to use the new macros, we use a single static "int" percpu variable, lowering the memory and cpu costs, still preserving NUMA efficiency. Signed-off-by: Eric Dumazet <dada1@cosmosbay.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/proc.c')
-rw-r--r--net/ipv4/proc.c19
1 files changed, 4 insertions, 15 deletions
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index ffdccc0972e0..ce34b281803f 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -46,17 +46,6 @@
46#include <net/sock.h> 46#include <net/sock.h>
47#include <net/raw.h> 47#include <net/raw.h>
48 48
49static int fold_prot_inuse(struct proto *proto)
50{
51 int res = 0;
52 int cpu;
53
54 for_each_possible_cpu(cpu)
55 res += proto->stats[cpu].inuse;
56
57 return res;
58}
59
60/* 49/*
61 * Report socket allocation statistics [mea@utu.fi] 50 * Report socket allocation statistics [mea@utu.fi]
62 */ 51 */
@@ -64,12 +53,12 @@ static int sockstat_seq_show(struct seq_file *seq, void *v)
64{ 53{
65 socket_seq_show(seq); 54 socket_seq_show(seq);
66 seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %d\n", 55 seq_printf(seq, "TCP: inuse %d orphan %d tw %d alloc %d mem %d\n",
67 fold_prot_inuse(&tcp_prot), atomic_read(&tcp_orphan_count), 56 sock_prot_inuse(&tcp_prot), atomic_read(&tcp_orphan_count),
68 tcp_death_row.tw_count, atomic_read(&tcp_sockets_allocated), 57 tcp_death_row.tw_count, atomic_read(&tcp_sockets_allocated),
69 atomic_read(&tcp_memory_allocated)); 58 atomic_read(&tcp_memory_allocated));
70 seq_printf(seq, "UDP: inuse %d\n", fold_prot_inuse(&udp_prot)); 59 seq_printf(seq, "UDP: inuse %d\n", sock_prot_inuse(&udp_prot));
71 seq_printf(seq, "UDPLITE: inuse %d\n", fold_prot_inuse(&udplite_prot)); 60 seq_printf(seq, "UDPLITE: inuse %d\n", sock_prot_inuse(&udplite_prot));
72 seq_printf(seq, "RAW: inuse %d\n", fold_prot_inuse(&raw_prot)); 61 seq_printf(seq, "RAW: inuse %d\n", sock_prot_inuse(&raw_prot));
73 seq_printf(seq, "FRAG: inuse %d memory %d\n", 62 seq_printf(seq, "FRAG: inuse %d memory %d\n",
74 ip_frag_nqueues(), ip_frag_mem()); 63 ip_frag_nqueues(), ip_frag_mem());
75 return 0; 64 return 0;