aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp
diff options
context:
space:
mode:
authorEric Dumazet <dada1@cosmosbay.com>2007-11-07 05:40:20 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2007-11-07 07:15:11 -0500
commit230140cffa7feae90ad50bf259db1fa07674f3a7 (patch)
tree815472add31606423a508a17806b7884f0ab3e2e /net/dccp
parentefac52762b1e3fe3035d29e82d8ee1aebc45e4a7 (diff)
[INET]: Remove per bucket rwlock in tcp/dccp ehash table.
As done two years ago on IP route cache table (commit 22c047ccbc68fa8f3fa57f0e8f906479a062c426) , we can avoid using one lock per hash bucket for the huge TCP/DCCP hash tables. On a typical x86_64 platform, this saves about 2MB or 4MB of ram, for litle performance differences. (we hit a different cache line for the rwlock, but then the bucket cache line have a better sharing factor among cpus, since we dirty it less often). For netstat or ss commands that want a full scan of hash table, we perform fewer memory accesses. Using a 'small' table of hashed rwlocks should be more than enough to provide correct SMP concurrency between different buckets, without using too much memory. Sizing of this table depends on num_possible_cpus() and various CONFIG settings. This patch provides some locking abstraction that may ease a future work using a different model for TCP/DCCP table. Signed-off-by: Eric Dumazet <dada1@cosmosbay.com> Acked-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dccp')
-rw-r--r--net/dccp/proto.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index d84973928033..7a3bea9c28c1 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -1072,11 +1072,13 @@ static int __init dccp_init(void)
1072 } 1072 }
1073 1073
1074 for (i = 0; i < dccp_hashinfo.ehash_size; i++) { 1074 for (i = 0; i < dccp_hashinfo.ehash_size; i++) {
1075 rwlock_init(&dccp_hashinfo.ehash[i].lock);
1076 INIT_HLIST_HEAD(&dccp_hashinfo.ehash[i].chain); 1075 INIT_HLIST_HEAD(&dccp_hashinfo.ehash[i].chain);
1077 INIT_HLIST_HEAD(&dccp_hashinfo.ehash[i].twchain); 1076 INIT_HLIST_HEAD(&dccp_hashinfo.ehash[i].twchain);
1078 } 1077 }
1079 1078
1079 if (inet_ehash_locks_alloc(&dccp_hashinfo))
1080 goto out_free_dccp_ehash;
1081
1080 bhash_order = ehash_order; 1082 bhash_order = ehash_order;
1081 1083
1082 do { 1084 do {
@@ -1091,7 +1093,7 @@ static int __init dccp_init(void)
1091 1093
1092 if (!dccp_hashinfo.bhash) { 1094 if (!dccp_hashinfo.bhash) {
1093 DCCP_CRIT("Failed to allocate DCCP bind hash table"); 1095 DCCP_CRIT("Failed to allocate DCCP bind hash table");
1094 goto out_free_dccp_ehash; 1096 goto out_free_dccp_locks;
1095 } 1097 }
1096 1098
1097 for (i = 0; i < dccp_hashinfo.bhash_size; i++) { 1099 for (i = 0; i < dccp_hashinfo.bhash_size; i++) {
@@ -1121,6 +1123,8 @@ out_free_dccp_mib:
1121out_free_dccp_bhash: 1123out_free_dccp_bhash:
1122 free_pages((unsigned long)dccp_hashinfo.bhash, bhash_order); 1124 free_pages((unsigned long)dccp_hashinfo.bhash, bhash_order);
1123 dccp_hashinfo.bhash = NULL; 1125 dccp_hashinfo.bhash = NULL;
1126out_free_dccp_locks:
1127 inet_ehash_locks_free(&dccp_hashinfo);
1124out_free_dccp_ehash: 1128out_free_dccp_ehash:
1125 free_pages((unsigned long)dccp_hashinfo.ehash, ehash_order); 1129 free_pages((unsigned long)dccp_hashinfo.ehash, ehash_order);
1126 dccp_hashinfo.ehash = NULL; 1130 dccp_hashinfo.ehash = NULL;
@@ -1139,6 +1143,7 @@ static void __exit dccp_fini(void)
1139 free_pages((unsigned long)dccp_hashinfo.ehash, 1143 free_pages((unsigned long)dccp_hashinfo.ehash,
1140 get_order(dccp_hashinfo.ehash_size * 1144 get_order(dccp_hashinfo.ehash_size *
1141 sizeof(struct inet_ehash_bucket))); 1145 sizeof(struct inet_ehash_bucket)));
1146 inet_ehash_locks_free(&dccp_hashinfo);
1142 kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep); 1147 kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep);
1143 dccp_ackvec_exit(); 1148 dccp_ackvec_exit();
1144 dccp_sysctl_exit(); 1149 dccp_sysctl_exit();