[TCP]: Document non-trivial locking path in tcp_v{4,6}_get_port().
authorDavid S. Miller <davem@davemloft.net>
Tue, 23 Aug 2005 17:49:54 +0000 (10:49 -0700)
committerDavid S. Miller <davem@davemloft.net>
Tue, 23 Aug 2005 17:49:54 +0000 (10:49 -0700)
This trips up a lot of folks reading this code.
Put an unlikely() around the port-exhaustion test
for good measure.

Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv4/tcp_ipv4.c
net/ipv6/tcp_ipv6.c

index 5d91213d34c06c2f52a9a3217cb1dc9a2ef4c5cc..67c670886c1fda8f3f8beb156e4b23b36888eae1 100644 (file)
@@ -242,9 +242,14 @@ static int tcp_v4_get_port(struct sock *sk, unsigned short snum)
                tcp_port_rover = rover;
                spin_unlock(&tcp_portalloc_lock);
 
-               /* Exhausted local port range during search? */
+               /* Exhausted local port range during search?  It is not
+                * possible for us to be holding one of the bind hash
+                * locks if this test triggers, because if 'remaining'
+                * drops to zero, we broke out of the do/while loop at
+                * the top level, not from the 'break;' statement.
+                */
                ret = 1;
-               if (remaining <= 0)
+               if (unlikely(remaining <= 0))
                        goto fail;
 
                /* OK, here is the one we will use.  HEAD is
index f6e288dc116ede93c2f755075c641303ca4bca47..ef29cfd936d3bed8f094f89627e8e67932529886 100644 (file)
@@ -158,9 +158,14 @@ static int tcp_v6_get_port(struct sock *sk, unsigned short snum)
                tcp_port_rover = rover;
                spin_unlock(&tcp_portalloc_lock);
 
-               /* Exhausted local port range during search? */
+               /* Exhausted local port range during search?  It is not
+                * possible for us to be holding one of the bind hash
+                * locks if this test triggers, because if 'remaining'
+                * drops to zero, we broke out of the do/while loop at
+                * the top level, not from the 'break;' statement.
+                */
                ret = 1;
-               if (remaining <= 0)
+               if (unlikely(remaining <= 0))
                        goto fail;
 
                /* OK, here is the one we will use. */