diff options
author | Harald Welte (local) <laflocal@hanuman.gnumonks.org> | 2009-12-27 18:12:29 +0100 |
---|---|---|
committer | Harald Welte (local) <laflocal@hanuman.gnumonks.org> | 2009-12-27 18:12:29 +0100 |
commit | 1fa3b78f4ae81bba8a750317aa684ddcbddc22cb (patch) | |
tree | 62dda9c4cba5496f3290148ed3de12bae293db6f /openbsc/src | |
parent | 945b8da98c669fb52dd9d105181fce434e064401 (diff) |
Introduce new ACT_REQ state to prevent race condition during channel allocation
When we allocate a channel, we send the RSL CHAN ACT REQ and wait until we get
a CHAN ACT ACK. Only the ACK will change the state, so there is a race where
we allocate that same channel to a different channel request before we get
the ACT ACK.
Introducing a new ACT_REQ state resolves this issue.
Diffstat (limited to 'openbsc/src')
-rw-r--r-- | openbsc/src/abis_rsl.c | 15 | ||||
-rw-r--r-- | openbsc/src/chan_alloc.c | 3 |
2 files changed, 12 insertions, 6 deletions
diff --git a/openbsc/src/abis_rsl.c b/openbsc/src/abis_rsl.c index a4c54190f..bd41283b7 100644 --- a/openbsc/src/abis_rsl.c +++ b/openbsc/src/abis_rsl.c @@ -957,12 +957,15 @@ static int rsl_rx_chan_act_nack(struct msgb *msg) return -EINVAL; rsl_tlv_parse(&tp, dh->data, msgb_l2len(msg)-sizeof(*dh)); - if (TLVP_PRESENT(&tp, RSL_IE_CAUSE)) - print_rsl_cause(LOGL_ERROR, TLVP_VAL(&tp, RSL_IE_CAUSE), + if (TLVP_PRESENT(&tp, RSL_IE_CAUSE)) { + const u_int8_t *cause = TLVP_VAL(&tp, RSL_IE_CAUSE); + print_rsl_cause(LOGL_ERROR, cause, TLVP_LEN(&tp, RSL_IE_CAUSE)); - - msg->lchan->state = LCHAN_S_NONE; - + if (*cause != RSL_ERR_RCH_ALR_ACTV_ALLOC) + msg->lchan->state = LCHAN_S_NONE; + } else + msg->lchan->state = LCHAN_S_NONE; + LOGPC(DRSL, LOGL_ERROR, "\n"); dispatch_signal(SS_LCHAN, S_LCHAN_ACTIVATE_NACK, msg->lchan); @@ -1298,6 +1301,8 @@ static int rsl_rx_chan_rqd(struct msgb *msg) return -ENOMEM; } + lchan->state = LCHAN_S_ACT_REQ; + ts_number = lchan->ts->nr; arfcn = lchan->ts->trx->arfcn; subch = lchan->nr; diff --git a/openbsc/src/chan_alloc.c b/openbsc/src/chan_alloc.c index 4bdf722b0..abf4de891 100644 --- a/openbsc/src/chan_alloc.c +++ b/openbsc/src/chan_alloc.c @@ -175,7 +175,8 @@ _lc_find_trx(struct gsm_bts_trx *trx, enum gsm_phys_chan_config pchan) /* check if all sub-slots are allocated yet */ for (ss = 0; ss < subslots_per_pchan[pchan]; ss++) { struct gsm_lchan *lc = &ts->lchan[ss]; - if (lc->type == GSM_LCHAN_NONE) + if (lc->type == GSM_LCHAN_NONE && + lc->state == LCHAN_S_NONE) return lc; } } |