From: Daniel Lezcano <[EMAIL PROTECTED]>

The network namespace cleanup will remove all timewait sockets
related to it because there are pointless. 

The problem is we need to browse the established hash table and 
for that we need to take the lock. For each timesocket we call 
inet_deschedule and this one take the established hash table lock
too.

The following patchset split the removing of the established hash
into two parts, one removing the node from the hash and another
taking the lock and calling the first one.

The network namespace cleanup can be done calling the lock free
function.

Signed-off-by: Daniel Lezcano <[EMAIL PROTECTED]>
---
 include/net/inet_timewait_sock.h |   13 ++++++++++++
 net/ipv4/inet_timewait_sock.c    |   40 +++++++++++++++++++++++++++------------
 2 files changed, 41 insertions(+), 12 deletions(-)

Index: linux-2.6-netns/net/ipv4/inet_timewait_sock.c
===================================================================
--- linux-2.6-netns.orig/net/ipv4/inet_timewait_sock.c
+++ linux-2.6-netns/net/ipv4/inet_timewait_sock.c
@@ -13,25 +13,28 @@
 #include <net/inet_timewait_sock.h>
 #include <net/ip.h>
 
-/* Must be called with locally disabled BHs. */
-static void __inet_twsk_kill(struct inet_timewait_sock *tw,
-                            struct inet_hashinfo *hashinfo)
+static inline int inet_twsk_unehash(struct inet_timewait_sock *tw,
+                                   struct inet_hashinfo *hashinfo)
 {
-       struct inet_bind_hashbucket *bhead;
-       struct inet_bind_bucket *tb;
-       /* Unlink from established hashes. */
-       struct inet_ehash_bucket *ehead = inet_ehash_bucket(hashinfo, 
tw->tw_hash);
+       struct inet_ehash_bucket *ehead =
+               inet_ehash_bucket(hashinfo, tw->tw_hash);
 
        write_lock(&ehead->lock);
-       if (hlist_unhashed(&tw->tw_node)) {
+       if (__inet_twsk_unehash(tw)) {
                write_unlock(&ehead->lock);
-               return;
+               return 1;
        }
-       __hlist_del(&tw->tw_node);
-       sk_node_init(&tw->tw_node);
        write_unlock(&ehead->lock);
 
-       /* Disassociate with bind bucket. */
+       return 0;
+}
+
+void inet_twsk_unbhash(struct inet_timewait_sock *tw,
+                      struct inet_hashinfo *hashinfo)
+{
+       struct inet_bind_hashbucket *bhead;
+       struct inet_bind_bucket *tb;
+
        bhead = &hashinfo->bhash[inet_bhashfn(tw->tw_net, tw->tw_num, 
hashinfo->bhash_size)];
        spin_lock(&bhead->lock);
        tb = tw->tw_tb;
@@ -39,6 +42,19 @@ static void __inet_twsk_kill(struct inet
        tw->tw_tb = NULL;
        inet_bind_bucket_destroy(hashinfo->bind_bucket_cachep, tb);
        spin_unlock(&bhead->lock);
+}
+
+/* Must be called with locally disabled BHs. */
+static void __inet_twsk_kill(struct inet_timewait_sock *tw,
+                            struct inet_hashinfo *hashinfo)
+{
+       /* Unlink from established hashes. */
+       if (inet_twsk_unehash(tw, hashinfo))
+               return;
+
+       /* Disassociate with bind bucket. */
+       inet_twsk_unbhash(tw, hashinfo);
+
 #ifdef SOCK_REFCNT_DEBUG
        if (atomic_read(&tw->tw_refcnt) != 1) {
                printk(KERN_DEBUG "%s timewait_sock %p refcnt=%d\n",
Index: linux-2.6-netns/include/net/inet_timewait_sock.h
===================================================================
--- linux-2.6-netns.orig/include/net/inet_timewait_sock.h
+++ linux-2.6-netns/include/net/inet_timewait_sock.h
@@ -173,6 +173,19 @@ static inline int inet_twsk_del_dead_nod
        return 0;
 }
 
+static inline int __inet_twsk_unehash(struct inet_timewait_sock *tw)
+{
+       if (hlist_unhashed(&tw->tw_node))
+               return 1;
+       __hlist_del(&tw->tw_node);
+       sk_node_init(&tw->tw_node);
+
+       return 0;
+}
+
+extern void inet_twsk_unbhash(struct inet_timewait_sock *tw,
+                             struct inet_hashinfo *hashinfo);
+
 #define inet_twsk_for_each(tw, node, head) \
        hlist_for_each_entry(tw, node, head, tw_node)
 

-- 
_______________________________________________
Containers mailing list
[EMAIL PROTECTED]
https://lists.linux-foundation.org/mailman/listinfo/containers

_______________________________________________
Devel mailing list
Devel@openvz.org
https://openvz.org/mailman/listinfo/devel

Reply via email to