Change in osmo-ttcn3-hacks[master]: library/RSL_Emulation: implement waiting queue for DCHAN messages

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/gerrit-log@lists.osmocom.org/.

fixeria gerrit-no-reply at lists.osmocom.org
Fri Jun 19 18:32:03 UTC 2020


fixeria has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/18923 )


Change subject: library/RSL_Emulation: implement waiting queue for DCHAN messages
......................................................................

library/RSL_Emulation: implement waiting queue for DCHAN messages

Since change [1] has been merged, we see multiple regressions in
ttcn3-bsc-test (all LCLS test cases) and ttcn3-bsc-test-sccplite
(sporadic failures). In all failed cases, the reason is similar:

  RSL for unknown Dchan
      BSC_Tests.ttcn:4501 BSC_Tests control part
      BSC_Tests.ttcn:2176 TC_assignment_codec_fr testcase

The mentioned change enables TCP_NODELAY option for all IPA based
connections, including both OML and RSL. This option disables
Nagle's algorithm [2], so we get less delays on IPA based links.

It took me a lot of time to investigate, and finally, I figured
out what is actually causing those regressions. The TCP_NODELAY
itself is not a problem, of course. As it turned out, the
problem is here, in our TTCN-3 test case framework.

Each test case involves several components (actors) running in parallel.
One of them is RSL_Emulation_CT, which is responsible for handling and
routing of RSL messages between the connected components.

A test case may register dedicated channel handlers by calling
f_rslem_register(), so DCHAN/RLL/IPACCESS messages will be matched
by RslChannelNr/TrxNr and routed to the corresponding one.

If no handler is found for a given RSL message, the RSL_Emulation_CT
would abort the test case execution. And that's where the problem is.

Given that all components are running in parallel, it may happen
that a received RSL message would be processed by the RSL emulation
component faster than the test case would call f_rslem_register().
The test case would be aborted due to "RSL for unknown Dchan".

Speaking in context of the failing BSC test cases, a test case
calls f_rslem_register() on receipt of an Assignment Command as
it contains all the assignment parameters. After that we expect
to receive an RSL ip.access CRCX for that channel.

The problem is that both Assignment Command and ip.access CRCX
messages are sent by the BSC simultaneously, so the later may
be handled faster than the first one. Race condition!

Let's work this around by maintaining a waiting queue, where the
messages, for which no handler was found, will be kept until the
corresponding dedicated channel is registered.

This is an optional feature that will be enabled by default, but
can be disabled by setting 'mp_rslem_enable_queue' to false.

Makes all LCLS test cases pass on my machine with TCP_NODELAY enabled.

[1] Ia3d4c41bf0659e682f0b7ae5f3d58ed0f28edb58
[2] https://en.wikipedia.org/wiki/Nagle%27s_algorithm

Change-Id: I25e10e28de174337233e6a3bb32cc16f2d7d614e
Related: OS#4619
---
M library/RSL_Emulation.ttcn
1 file changed, 38 insertions(+), 0 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-ttcn3-hacks refs/changes/23/18923/1

diff --git a/library/RSL_Emulation.ttcn b/library/RSL_Emulation.ttcn
index 618cf11..6108b4f 100644
--- a/library/RSL_Emulation.ttcn
+++ b/library/RSL_Emulation.ttcn
@@ -39,6 +39,10 @@
 	/* Work around switch for ttcn3-bts-test-latest, enables patching of IPA
 	 * stream ID in the "BSC" mode. See I5927f59a49724170a63e87be604973f7c9d5d8be. */
 	boolean mp_rslem_patch_ipa_cid := false;
+	/* Whether to keep RSL messages, for which no handler is found in ConnectionTable,
+	 * in a queue. These messages will remain in the queue until the appropriate
+	 * connection handler is registered. */
+	boolean mp_rslem_enable_queue := true;
 };
 
 /* General "base class" component definition, of which specific implementations
@@ -415,6 +419,8 @@
 	testcase.stop("Failed to patch IPA stream ID in ASP RSL UD: ", ud);
 }
 
+private type record of ASP_RSL_Unitdata ASP_RSL_UDList;
+
 type component RSL_Emulation_CT {
 	/* port facing down towards IPA emulation */
 	port IPA_RSL_PT IPA_PT;
@@ -428,6 +434,9 @@
 	/* state of all concurrent connections / dedicated channels */
 	var ConnectionData ConnectionTable[64];
 
+	/* RSL messages for which no handler is currently registered */
+	var ASP_RSL_UDList WaitingQueue := { };
+
 	/* last RSL CHAN ACT for each chan_nr */
 	var LastActData LastActTable[64];
 
@@ -584,6 +593,9 @@
 						rx_rsl.rsl.ies[0].body.chan_nr);
 			if (cid != -1) {
 				CLIENT_PT.send(rx_rsl.rsl) to ConnectionTable[cid].comp_ref;
+			} else if (mp_rslem_enable_queue) {
+				log("Storing an RSL message in the waiting queue");
+				WaitingQueue := WaitingQueue & { rx_rsl };
 			} else {
 				setverdict(fail, "RSL for unknown Dchan");
 				mtc.stop;
@@ -630,6 +642,10 @@
 		[] RSL_PROC.getcall(RSLEM_register:{?,?,?}) -> param(trx_nr, chan_nr, vc_conn) {
 			f_cid_create_cnr(trx_nr, chan_nr, vc_conn);
 			RSL_PROC.reply(RSLEM_register:{trx_nr, chan_nr, vc_conn}) to vc_conn;
+
+			/* Dispatch pending messages to the new handler (if any) */
+			if (mp_rslem_enable_queue)
+				{ f_WaitingQueue_process(trx_nr, chan_nr, vc_conn); }
 			}
 
 		[] RSL_PROC.getcall(RSLEM_unregister:{?,?,?}) -> param(trx_nr, chan_nr, vc_conn) {
@@ -668,6 +684,28 @@
 	}
 }
 
+private function f_WaitingQueue_process(uint8_t trx_nr, RslChannelNr chan_nr,
+					RSL_DchanHdlr comp_ref)
+runs on RSL_Emulation_CT {
+	var ASP_RSL_UDList NewWaitingQueue := { };
+
+	/* NOTE: we cannot (safely) remove elements in the loop, so we create
+	 * a new queue with not matching messages and then replace the old one. */
+	for (var integer i := 0; i < lengthof(WaitingQueue); i := i + 1) {
+		if (f_trx_by_streamId(WaitingQueue[i].streamId) == trx_nr and
+		    WaitingQueue[i].rsl.ies[0].body.chan_nr == chan_nr) {
+			/* Matched, send this message to the given RSL_DchanHdlr */
+			log("Dispatching a stalled message to ", comp_ref);
+			CLIENT_PT.send(WaitingQueue[i].rsl) to comp_ref;
+		} else {
+			/* Does not match, put this one into the new queue */
+			NewWaitingQueue := NewWaitingQueue & { WaitingQueue[i] };
+		}
+	}
+
+	WaitingQueue := NewWaitingQueue;
+}
+
 /* client/conn_hdlr side function to use procedure port to register stream_id/chan_nr */
 function f_rslem_register(uint8_t trx_nr, RslChannelNr chan_nr, RSLEM_PROC_PT PT := RSL_PROC)
 runs on RSL_DchanHdlr {

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/18923
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-ttcn3-hacks
Gerrit-Branch: master
Gerrit-Change-Id: I25e10e28de174337233e6a3bb32cc16f2d7d614e
Gerrit-Change-Number: 18923
Gerrit-PatchSet: 1
Gerrit-Owner: fixeria <vyanitskiy at sysmocom.de>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200619/bc634d19/attachment.htm>


More information about the gerrit-log mailing list