pr_debug("%s: begins, snum:%d\n", __func__, snum);
 
-       local_bh_disable();
-
        if (snum == 0) {
                /* Search for an available port. */
                int low, high, remaining, index;
                                continue;
                        index = sctp_phashfn(net, rover);
                        head = &sctp_port_hashtable[index];
-                       spin_lock(&head->lock);
+                       spin_lock_bh(&head->lock);
                        sctp_for_each_hentry(pp, &head->chain)
                                if ((pp->port == rover) &&
                                    net_eq(net, pp->net))
                                        goto next;
                        break;
                next:
-                       spin_unlock(&head->lock);
+                       spin_unlock_bh(&head->lock);
+                       cond_resched();
                } while (--remaining > 0);
 
                /* Exhausted local port range during search? */
                ret = 1;
                if (remaining <= 0)
-                       goto fail;
+                       return ret;
 
                /* OK, here is the one we will use.  HEAD (the port
                 * hash table list entry) is non-NULL and we hold it's
                 * port iterator, pp being NULL.
                 */
                head = &sctp_port_hashtable[sctp_phashfn(net, snum)];
-               spin_lock(&head->lock);
+               spin_lock_bh(&head->lock);
                sctp_for_each_hentry(pp, &head->chain) {
                        if ((pp->port == snum) && net_eq(pp->net, net))
                                goto pp_found;
        ret = 0;
 
 fail_unlock:
-       spin_unlock(&head->lock);
-
-fail:
-       local_bh_enable();
+       spin_unlock_bh(&head->lock);
        return ret;
 }