rwlock_t                        lhash_lock ____cacheline_aligned;
        atomic_t                        lhash_users;
        wait_queue_head_t               lhash_wait;
-       spinlock_t                      portalloc_lock;
        kmem_cache_t                    *bind_bucket_cachep;
-       int                             port_rover;
 };
 
 static inline unsigned int inet_ehashfn(const __u32 laddr, const __u16 lport,
 
        .lhash_lock     = RW_LOCK_UNLOCKED,
        .lhash_users    = ATOMIC_INIT(0),
        .lhash_wait = __WAIT_QUEUE_HEAD_INITIALIZER(dccp_hashinfo.lhash_wait),
-       .portalloc_lock = SPIN_LOCK_UNLOCKED,
-       .port_rover     = 1024 - 1,
 };
 
 EXPORT_SYMBOL_GPL(dccp_hashinfo);
        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;
+               int rover = net_random() % (high - low) + low;
                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);
 
                next_port:
                        spin_unlock(&head->lock);
+                       if (++rover > high)
+                               rover = low;
                } while (--remaining > 0);
-               dccp_hashinfo.port_rover = rover;
-               spin_unlock(&dccp_hashinfo.portalloc_lock);
 
                local_bh_enable();
 
 
 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);
 
                int low = sysctl_local_port_range[0];
                int high = sysctl_local_port_range[1];
                int remaining = (high - low) + 1;
-               int rover;
+               int rover = net_random() % (high - low) + low;
 
-               spin_lock(&hashinfo->portalloc_lock);
-               if (hashinfo->port_rover < low)
-                       rover = low;
-               else
-                       rover = hashinfo->port_rover;
                do {
-                       rover++;
-                       if (rover > high)
-                               rover = low;
                        head = &hashinfo->bhash[inet_bhashfn(rover, hashinfo->bhash_size)];
                        spin_lock(&head->lock);
                        inet_bind_bucket_for_each(tb, node, &head->chain)
                        break;
                next:
                        spin_unlock(&head->lock);
+                       if (++rover > high)
+                               rover = low;
                } while (--remaining > 0);
-               hashinfo->port_rover = rover;
-               spin_unlock(&hashinfo->portalloc_lock);
 
                /* Exhausted local port range during search?  It is not
                 * possible for us to be holding one of the bind hash
 
                sysctl_tcp_max_orphans >>= (3 - order);
                sysctl_max_syn_backlog = 128;
        }
-       tcp_hashinfo.port_rover = sysctl_local_port_range[0] - 1;
 
        sysctl_tcp_mem[0] =  768 << order;
        sysctl_tcp_mem[1] = 1024 << order;
 
        .lhash_lock     = RW_LOCK_UNLOCKED,
        .lhash_users    = ATOMIC_INIT(0),
        .lhash_wait     = __WAIT_QUEUE_HEAD_INITIALIZER(tcp_hashinfo.lhash_wait),
-       .portalloc_lock = SPIN_LOCK_UNLOCKED,
-       .port_rover     = 1024 - 1,
 };
 
 static int tcp_v4_get_port(struct sock *sk, unsigned short snum)
 
                int low = sysctl_local_port_range[0];
                int high = sysctl_local_port_range[1];
                int remaining = (high - low) + 1;
-               int rover;
+               int rover = net_random() % (high - low) + low;
 
-               spin_lock(&tcp_hashinfo.portalloc_lock);
-               if (tcp_hashinfo.port_rover < low)
-                       rover = low;
-               else
-                       rover = tcp_hashinfo.port_rover;
-               do {    rover++;
-                       if (rover > high)
-                               rover = low;
+               do {
                        head = &tcp_hashinfo.bhash[inet_bhashfn(rover, tcp_hashinfo.bhash_size)];
                        spin_lock(&head->lock);
                        inet_bind_bucket_for_each(tb, node, &head->chain)
                        break;
                next:
                        spin_unlock(&head->lock);
+                       if (++rover > high)
+                               rover = low;
                } while (--remaining > 0);
-               tcp_hashinfo.port_rover = rover;
-               spin_unlock(&tcp_hashinfo.portalloc_lock);
 
                /* Exhausted local port range during search?  It is not
                 * possible for us to be holding one of the bind hash