 /* TODO. Actually it is not so bad idea to remove * dccp_hashinfo.portalloc_lock before next submission to * Linus. * As soon as we touch this place at all it is time to think. * * Now it protects single _advisory_ variable * dccp_hashinfo.port_rover, hence it is mostly useless. * Code will work nicely if we just delete it, but * I am afraid in contented case it will work not better or * even worse: another cpu just will hit the same bucket * and spin there. * So some cpu salt could remove both contention and * memory pingpong. Any ideas how to do this in a nice way? */ spin_lock(&dccp_hashinfo.portalloc_lock); rover = dccp_hashinfo.port_rover;  
static int dccp_v4_hash_connect(struct sock *sk){	const unsigned short snum = inet_sk(sk)->num; 	struct inet_bind_hashbucket *head; 	struct inet_bind_bucket *tb;	int ret; 	if (snum == 0) { 		int rover; 		int low = sysctl_local_port_range[0]; 		int high = sysctl_local_port_range[1]; 		int remaining = (high - low) + 1;		struct hlist_node *node; 		struct inet_timewait_sock *tw = NULL; 		local_bh_disable(); 		/* TODO. Actually it is not so bad idea to remove 		 * dccp_hashinfo.portalloc_lock before next submission to		 * Linus. 		 * As soon as we touch this place at all it is time to think. 		 * 		 * Now it protects single _advisory_ variable		 * dccp_hashinfo.port_rover, hence it is mostly useless. 		 * Code will work nicely if we just delete it, but 		 * I am afraid in contented case it will work not better or 		 * even worse: another cpu just will hit the same bucket 		 * and spin there. 		 * So some cpu salt could remove both contention and 		 * memory pingpong. Any ideas how to do this in a nice way? 		 */ 		spin_lock(&dccp_hashinfo.portalloc_lock); 		rover = dccp_hashinfo.port_rover; 		do { 			rover++; 			if ((rover < low) || (rover > high)) 				rover = low; 			head = &dccp_hashinfo.bhash[inet_bhashfn(rover,						    dccp_hashinfo.bhash_size)]; 			spin_lock(&head->lock); 			/* Does not bother with rcv_saddr checks, 			 * because the established check is already 			 * unique enough. 			 */			inet_bind_bucket_for_each(tb, node, &head->chain) { 				if (tb->port == rover) { 					BUG_TRAP(!hlist_empty(&tb->owners)); 					if (tb->fastreuse >= 0) 						goto next_port; 					if (!__dccp_v4_check_established(sk,									 rover,									 &tw)) 						goto ok; 					goto next_port; 				} 			} 			tb = inet_bind_bucket_create(dccp_hashinfo.bind_bucket_cachep,						     head, rover); 			if (tb == NULL) { 				spin_unlock(&head->lock); 				break; 			} 			tb->fastreuse = -1; 			goto ok; 		next_port: 			spin_unlock(&head->lock); 		} while (--remaining > 0); 		dccp_hashinfo.port_rover = rover; 		spin_unlock(&dccp_hashinfo.portalloc_lock); 		local_bh_enable(); 		return -EADDRNOTAVAIL;ok: 		/* All locks still held and bhs disabled */ 		dccp_hashinfo.port_rover = rover; 		spin_unlock(&dccp_hashinfo.portalloc_lock); 		inet_bind_hash(sk, tb, rover);		if (sk_unhashed(sk)) { 			inet_sk(sk)->sport = htons(rover); 			__inet_hash(&dccp_hashinfo, sk, 0); 		} 		spin_unlock(&head->lock); 		if (tw != NULL) { 			inet_twsk_deschedule(tw, &dccp_death_row); 			inet_twsk_put(tw); 		}		ret = 0;		goto out; 	} 	head = &dccp_hashinfo.bhash[inet_bhashfn(snum,						 dccp_hashinfo.bhash_size)]; 	tb   = inet_csk(sk)->icsk_bind_hash;	spin_lock_bh(&head->lock);	if (sk_head(&tb->owners) == sk && sk->sk_bind_node.next == NULL) {		__inet_hash(&dccp_hashinfo, sk, 0);		spin_unlock_bh(&head->lock);		return 0;	} else {		spin_unlock(&head->lock);		/* No definite answer... Walk to established hash table */		ret = __dccp_v4_check_established(sk, snum, NULL);out:		local_bh_enable();		return ret;	}}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/6df716340da3a6fdd33d73d7ed4c6f7590ca1c42/ipv4.c/clean/net/dccp/ipv4.c