Unbounded AGCH queue in OsmoBTS

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/OpenBSC@lists.osmocom.org/.

Jacob Erlbeck jerlbeck at sysmocom.de
Tue Feb 11 14:07:13 UTC 2014


Dear Ivan,

since I've been investigating this topic for some days now, I would like
to share my thoughts about your approach, so that we can resolve this
issue quickly together.

On 11.02.2014 08:13, Ivan Kluchnikov wrote:
> 1. Implementation of sending rsl Delete_Ind message (on bts side) and
> handling it (on bsc side).
> Bts should send rsl Delete Ind message to bsc, if there is no space in
> agch queue and bts can not send current imm assign message.
> When bsc receives Delete_Ind message from bts, bsc should release
> allocated channel, which was specified in dropped imm_assign message.

As far as I understand it is not important to send such messages to
IMMEDIATE ASSIGNMENT REJECT messages. But I like this idea to shorten
the timeout.

> 2. Implemented calculation of  agch queue length.
> Bts should calculate allowed length of agch queue, because bts should
> send imm assign message before immediate assignment procedure will be
> aborted by MS.
> Imm assign message can be queued no longer than T3126, so agch queue
> length should be equal (T3126 / 51 ) * bs_ag_blks_res.

I'm not sure about the correctness of the max length calculation because of
a) There are other timers/conditions that are influenced by the queue delay:
   - T3101 limits channel reservation on the network side.
   - Only the last 3 CHANNEL REQUEST messages are matched by the MS
     against incoming IMMEDIATE ASSIGNMENT messages.
b) If the queue has the length limited by a) we know that at least
   the last (if not every) element of the queue will be delivered too
   late.

Since your patch isn't using T3126 but min(T3126) which is based on
T + 2*S, and since this reflects the 3 CHAN-REQ restriction, this is
already solved (T3101 is probably larger that min(T3126)).
I'll use
  maxL = (min(T3126) / 51 ) * bs_ag_blks_res
below.

The b) issue is another thing. Because of additional round-trip delays
(DSP queues, BSC<->BTS delay) it might be sensible to reduce the max
queue length by another factor. But AFAICS the main problem with
dropping packets at the queue's input is, that you maintain a queue with
stale messages while throwing away the fresh ones. So under heavy load,
latency increases which is especially bad with IMMEDIATE ASSIGNMENT
messages.

I've two slightly different proposals to fix this:

(1) If the queue is full (e.g. at 0.8 * maxL), flush all IMMEDIATE
ASSIGNMENT REJECT messages. Don't notify the BSC about those. If there
are still too many messages left afterwards one might also drop an
IMMEDIATE ASSIGNMENT (perhaps from the queues input) and notify the BSC
like in your patch.

(2) When taking message from the queue, throw them away if they are
IMMEDIATE ASSIGNMENT REJECTs and the queue is too long (e.g. > maxL/2)
and try the next message until that condition fails (or some low water
mark is reached). A variant would be to drop IA REJECTs based on a queue
usage dependant probability (e.g. p(L) = L / maxL).

I'm not sure, which approach would perform better considering different
scenarios like burst-like accesses and high packet loss. I've done hand
simulations for a single burst case (10 MS compete simultaneously for 4
channels) and both approaches worked well (much better than the current
master). (2) is probably easier to implement.

What do you think about that?

> 
> These patches fix critical issues and prevent network failures under
> heavy load,

I'm not convinced that this approach will work reliably under overload
(see above). It just guarantees a maximum queue length.

> so it makes sense to merge them asap.

What about rebasing on on origin/master? I think that would speed this
up a lot. Is there something missing from jolly's branch beside queue
length accounting?

> @@ -50,6 +50,7 @@ struct gsm_bts_role_bts {
>  	uint8_t max_ta;
>  	struct llist_head agch_queue;
>  	int agch_queue_count;

I'd rather not use this name, but agch_queue_length instead. I think
'length' more precise than 'size' or 'count' when asking for the number
of elements of a list or a queue. 'count' makes me think about the
number of queues. Quite a few libraries have chosen 'size' instead, but
it's ambiguous, whether this refers to memory size or to the number of
elements.

> +	uint8_t agch_queue_len;

What about agch_max_queue_length or agch_queue_length_limit?

>  int bts_agch_enqueue(struct gsm_bts *bts, struct msgb *msg)
>  {
>  	struct gsm_bts_role_bts *btsb = bts_role_bts(bts);
> +	struct gsm48_system_information_type_3 *si3;
> +	uint8_t T, S, agch_num, i;
> +	uint8_t T_group = 0;
> +	uint8_t ccch_comb = 0;
> +
> +	/* calculate length of agch queue
> +	agch_queue_len =  ( min( T3126 ) / 51 ) * bs_ag_blks_res
> +	min(T3126) = T + 2*S defined in 04.08 11.1.1

Are you sure? Isn't it
        min(T3126) = (T + 2*S) / (RACH slots per second) ?

> +	S and T are defined in  04.08 3.3.1.1.2 */
> +
> +	si3 = GSM_BTS_SI(bts, SYSINFO_TYPE_3);
> +	T = si3->rach_control.tx_integer;
> +	for (i = 0; i < 15; i++) {
> +		if (tx_integer[i] == T) {
> +			T_group = i % 5;
> +			break;
> +		}
> +	}
> +	if (si3->control_channel_desc.ccch_conf == 1) {
> +		ccch_comb = 1;
> +	}
> +	S = s_values[T_group][ccch_comb];
> +	agch_num = si3->control_channel_desc.bs_ag_blks_res;
>  
> -	if (btsb->agch_queue_count >= 30)
> +	btsb->agch_queue_len = ((T + 2 * S) / 51) * agch_num;

This might lead to smaller values than neccessary due to rounding
errors. Why not using agch_queue_len = (??? * agch_num) / 51?
But I think, the max length computation does not yield correct results
anyway because of the number of RACH slots is not taken into account.

I'd rather put the above into an own function
(bts_agch_update_max_queue_length?) that is only called after
config/bs_ag_blks_res is changed/set.

Best wishes

Jacob





More information about the OpenBSC mailing list