patch-2.3.4 linux/net/ipv4/udp.c

Next file: linux/net/ipv6/addrconf.c
Previous file: linux/net/ipv4/timer.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.3/linux/net/ipv4/udp.c linux/net/ipv4/udp.c
@@ -5,7 +5,7 @@
  *
  *		The User Datagram Protocol (UDP).
  *
- * Version:	$Id: udp.c,v 1.66 1999/05/08 20:00:25 davem Exp $
+ * Version:	$Id: udp.c,v 1.67 1999/05/27 00:37:50 davem Exp $
  *
  * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
  *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -128,7 +128,7 @@
 	struct sock *sk2;
 	int retval = 0, sk_reuse = sk->reuse;
 
-	SOCKHASH_LOCK();
+	SOCKHASH_LOCK_READ();
 	for(sk2 = udp_hash[snum & (UDP_HTABLE_SIZE - 1)]; sk2 != NULL; sk2 = sk2->next) {
 		if((sk2->num == snum) && (sk2 != sk)) {
 			unsigned char state = sk2->state;
@@ -158,7 +158,7 @@
 			}
 		}
 	}
-	SOCKHASH_UNLOCK();
+	SOCKHASH_UNLOCK_READ();
 	return retval;
 }
 
@@ -180,7 +180,7 @@
 	static int start = 0;
 	int i, best, best_size_so_far;
 
-	SOCKHASH_LOCK();
+	SOCKHASH_LOCK_READ();
         if (start > sysctl_local_port_range[1] || start < sysctl_local_port_range[0])
                 start = sysctl_local_port_range[0];
 
@@ -223,15 +223,10 @@
         }
 out:
 	start = result;
-	SOCKHASH_UNLOCK();
+	SOCKHASH_UNLOCK_READ();
 	return result;
 }
 
-/* Last hit UDP socket cache, this is ipv4 specific so make it static. */
-static u32 uh_cache_saddr, uh_cache_daddr;
-static u16 uh_cache_dport, uh_cache_sport;
-static struct sock *uh_cache_sk = NULL;
-
 static void udp_v4_hash(struct sock *sk)
 {
 	struct sock **skp;
@@ -240,11 +235,11 @@
 	num &= (UDP_HTABLE_SIZE - 1);
 	skp = &udp_hash[num];
 
-	SOCKHASH_LOCK();
+	SOCKHASH_LOCK_WRITE();
 	sk->next = *skp;
 	*skp = sk;
 	sk->hashent = num;
-	SOCKHASH_UNLOCK();
+	SOCKHASH_UNLOCK_WRITE();
 }
 
 static void udp_v4_unhash(struct sock *sk)
@@ -255,7 +250,7 @@
 	num &= (UDP_HTABLE_SIZE - 1);
 	skp = &udp_hash[num];
 
-	SOCKHASH_LOCK();
+	SOCKHASH_LOCK_WRITE();
 	while(*skp != NULL) {
 		if(*skp == sk) {
 			*skp = sk->next;
@@ -263,9 +258,7 @@
 		}
 		skp = &((*skp)->next);
 	}
-	if(uh_cache_sk == sk)
-		uh_cache_sk = NULL;
-	SOCKHASH_UNLOCK();
+	SOCKHASH_UNLOCK_WRITE();
 }
 
 static void udp_v4_rehash(struct sock *sk)
@@ -277,7 +270,7 @@
 	num &= (UDP_HTABLE_SIZE - 1);
 	skp = &udp_hash[oldnum];
 
-	SOCKHASH_LOCK();
+	SOCKHASH_LOCK_WRITE();
 	while(*skp != NULL) {
 		if(*skp == sk) {
 			*skp = sk->next;
@@ -288,13 +281,11 @@
 	sk->next = udp_hash[num];
 	udp_hash[num] = sk;
 	sk->hashent = num;
-	if(uh_cache_sk == sk)
-		uh_cache_sk = NULL;
-	SOCKHASH_UNLOCK();
+	SOCKHASH_UNLOCK_WRITE();
 }
 
 /* UDP is nearly always wildcards out the wazoo, it makes no sense to try
- * harder than this here plus the last hit cache. -DaveM
+ * harder than this. -DaveM
  */
 struct sock *udp_v4_lookup_longway(u32 saddr, u16 sport, u32 daddr, u16 dport, int dif)
 {
@@ -341,21 +332,9 @@
 {
 	struct sock *sk;
 
-	if(!dif && uh_cache_sk		&&
-	   uh_cache_saddr == saddr	&&
-	   uh_cache_sport == sport	&&
-	   uh_cache_dport == dport	&&
-	   uh_cache_daddr == daddr)
-		return uh_cache_sk;
-
+	SOCKHASH_LOCK_READ();
 	sk = udp_v4_lookup_longway(saddr, sport, daddr, dport, dif);
-	if(!dif) {
-		uh_cache_sk	= sk;
-		uh_cache_saddr	= saddr;
-		uh_cache_daddr	= daddr;
-		uh_cache_sport	= sport;
-		uh_cache_dport	= dport;
-	}
+	SOCKHASH_UNLOCK_READ();
 	return sk;
 }
 
@@ -393,7 +372,7 @@
 			paddr = idev->ifa_list->ifa_local;
 	}
 
-	SOCKHASH_LOCK();
+	SOCKHASH_LOCK_READ();
 	for(s = udp_v4_proxy_loop_init(hnum, hpnum, s, firstpass);
 	    s != NULL;
 	    s = udp_v4_proxy_loop_next(hnum, hpnum, s, firstpass)) {
@@ -431,7 +410,7 @@
 			}
 		}
 	}
-	SOCKHASH_UNLOCK();
+	SOCKHASH_UNLOCK_READ();
 	return result;
 }
 
@@ -979,8 +958,6 @@
 		sk->rcv_saddr=INADDR_ANY;
 		sk->daddr=INADDR_ANY;
 		sk->state = TCP_CLOSE;
-		if(uh_cache_sk == sk)
-			uh_cache_sk = NULL;
 		return 0;
 	}
 
@@ -1005,9 +982,6 @@
 	sk->dport = usin->sin_port;
 	sk->state = TCP_ESTABLISHED;
 
-	if(uh_cache_sk == sk)
-		uh_cache_sk = NULL;
-
 	sk->dst_cache = &rt->u.dst;
 	return(0);
 }
@@ -1015,6 +989,8 @@
 
 static void udp_close(struct sock *sk, long timeout)
 {
+	bh_lock_sock(sk);
+
 	/* See for explanation: raw_close in ipv4/raw.c */
 	sk->state = TCP_CLOSE;
 	udp_v4_unhash(sk);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)