/* Allocate storage for the negotiated streams if it is not a temporary * association.
*/
if (!asoc->temp) {
- sctp_assoc_t assoc_id;
+ int assoc_id;
+ int error;
asoc->ssnmap = sctp_ssnmap_new(asoc->c.sinit_max_instreams,
asoc->c.sinit_num_ostreams, gfp);
if (!asoc->ssnmap)
goto clean_up;
- do {
- if (unlikely(!idr_pre_get(&sctp_assocs_id, gfp)))
- goto clean_up;
- spin_lock_bh(&sctp_assocs_id_lock);
- assoc_id = (sctp_assoc_t)idr_get_new(&sctp_assocs_id,
- (void *)asoc);
- spin_unlock_bh(&sctp_assocs_id_lock);
- } while (unlikely((int)assoc_id == -1));
+ retry:
+ if (unlikely(!idr_pre_get(&sctp_assocs_id, gfp)))
+ goto clean_up;
+ spin_lock_bh(&sctp_assocs_id_lock);
+ error = idr_get_new_above(&sctp_assocs_id, (void *)asoc, 1,
+ &assoc_id);
+ spin_unlock_bh(&sctp_assocs_id_lock);
+ if (error == -EAGAIN)
+ goto retry;
+ else if (error)
+ goto clean_up;
- asoc->assoc_id = assoc_id;
+ asoc->assoc_id = (sctp_assoc_t) assoc_id;
}
/* ADDIP Section 4.1 ASCONF Chunk Procedures