aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/inet_hashtables.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@ghostprotocols.net>2005-08-09 23:08:09 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2005-08-29 18:41:49 -0400
commitf3f05f7046e7c85b04af390d95a82a27160dd5d0 (patch)
tree9a4a552c030ea8b2428ceee75311d73a6b339255 /net/ipv4/inet_hashtables.c
parent6e04e02165a7209a71db553b7bc48d68421e5ebf (diff)
[INET]: Generalise the tcp_listen_ lock routines
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/inet_hashtables.c')
-rw-r--r--net/ipv4/inet_hashtables.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index 33d6cbe32cdc..06cbc6f689c5 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -15,7 +15,9 @@
15 15
16#include <linux/config.h> 16#include <linux/config.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/sched.h>
18#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/wait.h>
19 21
20#include <net/inet_hashtables.h> 22#include <net/inet_hashtables.h>
21 23
@@ -89,3 +91,33 @@ void inet_put_port(struct inet_hashinfo *hashinfo, struct sock *sk)
89} 91}
90 92
91EXPORT_SYMBOL(inet_put_port); 93EXPORT_SYMBOL(inet_put_port);
94
95/*
96 * This lock without WQ_FLAG_EXCLUSIVE is good on UP and it can be very bad on SMP.
97 * Look, when several writers sleep and reader wakes them up, all but one
98 * immediately hit write lock and grab all the cpus. Exclusive sleep solves
99 * this, _but_ remember, it adds useless work on UP machines (wake up each
100 * exclusive lock release). It should be ifdefed really.
101 */
102void inet_listen_wlock(struct inet_hashinfo *hashinfo)
103{
104 write_lock(&hashinfo->lhash_lock);
105
106 if (atomic_read(&hashinfo->lhash_users)) {
107 DEFINE_WAIT(wait);
108
109 for (;;) {
110 prepare_to_wait_exclusive(&hashinfo->lhash_wait,
111 &wait, TASK_UNINTERRUPTIBLE);
112 if (!atomic_read(&hashinfo->lhash_users))
113 break;
114 write_unlock_bh(&hashinfo->lhash_lock);
115 schedule();
116 write_lock_bh(&hashinfo->lhash_lock);
117 }
118
119 finish_wait(&hashinfo->lhash_wait, &wait);
120 }
121}
122
123EXPORT_SYMBOL(inet_listen_wlock);