AllocTest: Avoid queuing tons of to-be-freed ms

When both TBFs (Dl, Ul), are detached, ms_detach_tbf() will call
ms_start_timer() which will hold a reference of the MS (ms_ref()) and
wait for X seconds (VTY config, T=-2030, 60 seconds by default) before
unrefing the MS, which will trigger ms_update_status() finally (ref==0)
and will in turn call cb.ms_idle(), which will tell the ms_storage to
free the MS.

This mechanism is used to keep MS objects around for a certain time so
that when new TBFs are established, we have cached interesting
information about the MS, ready to use.

However, in AllocTest, tons of MS are allocated in a loop calling a
function (such as test_alloc_b_ul_dl()). In that function, a BTS is
allocated in the stack and at the end of the function BTS::cleanup() is
called due to implicit destructor, which ends up calling
ms_storage::cleanup() which removes all MS from its list and frees them
*if they are not idle*. The problem here, is that due to T=-2030, an
extra reference is hold and hence the ms is not considered idle
(ms_is_idle() checks ms->ref==0). As a result, the MS is never freed,
because we don't use libosmocore mainloop here (and in any case, it
would take 60 seconds to free it).

By setting the timeout of T=-2030 to 0, ms_start_timer will avoid using
the timer and will also avoid holding the extra reference, hence
allowing ms_storage to free the object during cleanup().

This fix really helps in improving performance for AllocTest specially
after MS object contains a rate_ctr. As tons of MS objects were left
alive, they stood in the rate_ctr single per-process queue, making the
test last crazy amount of time and spending 50% of the time or more
iterating the list full of MS related rate counters.

Change-Id: I6b6ebe8903e4fe76da5e09b02b6ef28542007b6c
This commit is contained in:
Pau Espin 2021-01-11 20:40:19 +01:00 committed by laforge
parent bed48cc14f
commit 1e00947c29
1 changed files with 6 additions and 0 deletions

View File

@ -219,6 +219,8 @@ static inline bool test_alloc_b_ul_dl(bool ts0, bool ts1, bool ts2, bool ts3, bo
enable_ts_on_bts(bts, ts0, ts1, ts2, ts3, ts4, ts5, ts6, ts7);
ms = the_bts.ms_alloc(ms_class, 0);
/* Avoid delaying free to avoid tons of to-be-freed ms objects queuing */
ms_set_timeout(ms, 0);
ul_tbf = tbf_alloc_ul_tbf(bts, ms, -1, true);
if (!ul_tbf)
return false;
@ -262,6 +264,8 @@ static inline bool test_alloc_b_dl_ul(bool ts0, bool ts1, bool ts2, bool ts3, bo
enable_ts_on_bts(bts, ts0, ts1, ts2, ts3, ts4, ts5, ts6, ts7);
ms = the_bts.ms_alloc(ms_class, 0);
/* Avoid delaying free to avoid tons of to-be-freed ms objects queuing */
ms_set_timeout(ms, 0);
dl_tbf = tbf_alloc_dl_tbf(bts, ms, -1, true);
if (!dl_tbf)
return false;
@ -314,6 +318,8 @@ static inline bool test_alloc_b_jolly(uint8_t ms_class)
tfi = the_bts.tfi_find_free(GPRS_RLCMAC_UL_TBF, &trx_no, -1);
OSMO_ASSERT(tfi >= 0);
ms = the_bts.ms_alloc(ms_class, 0);
/* Avoid delaying free to avoid tons of to-be-freed ms objects queuing */
ms_set_timeout(ms, 0);
ul_tbf = tbf_alloc_ul_tbf(bts, ms, -1, false);
if (!ul_tbf)
return false;